﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Linq.Expressions;
using System.Reflection;
using System.Deployment.Application;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;

namespace Medicine_Tracker_V3
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            if (!(new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator))
            {
                toolStripMenuItemExport.Image = Resources.uac;
            }
        }

        #region Form Events
        private void MainForm_Load(object sender, EventArgs e)
        {
            StartProcess("Loading Data...");
            BackgroundWorker bgwLoad = new BackgroundWorker();
            bgwLoad.DoWork += new DoWorkEventHandler(bgwLoad_DoWork);
            bgwLoad.RunWorkerAsync();
        }

        private void tabControlMain_Selected(object sender, TabControlEventArgs e)
        {
            BackgroundWorker bwLoad = new BackgroundWorker();
            StartProcess("Loading...");
            switch (e.TabPage.Name)
            {
                case "tabPageMedicines":
                    dataGridViewMain.DataSource = this.medicinesTableAdapter.GetData();
                    TitleCaseColumnHeaders();
                    groupBoxMedicines.Enabled = false;
                    buttonMedAdd.Enabled = false;
                    buttonMedUpdate.Enabled = false;
                    StopProcess();
                    break;
                case "tabPageAdministrations":
                    bwLoad.DoWork += delegate
                    {
                        SetDataBinding(this.administrationsTableAdapter.GetData());
                        TitleCaseColumnHeaders();
                        StopProcess();
                    };
                    bwLoad.RunWorkerAsync();
                    groupBoxAdmin7DayReview.Enabled = false;
                    buttonAdminAdd.Enabled = false;
                    buttonAdminUpdate.Enabled = false;
                    groupBoxAdministrations.Enabled = false;
                    dataGridViewGroup.Visible = false;
                    break;
                case "tabPagePurchases":
                    bwLoad.DoWork += delegate
                    {
                        SetDataBinding(this.purchasesTableAdapter.GetData());
                        TitleCaseColumnHeaders();
                        StopProcess();
                    };
                    bwLoad.RunWorkerAsync();
                    groupBoxPurchases.Enabled = false;
                    buttonPurAdd.Enabled = false;
                    buttonPurUpdate.Enabled = false;
                    break;
                case "tabPageDisposals":
                    bwLoad.DoWork += delegate
                   {
                       SetDataBinding(this.disposalsTableAdapter.GetData());
                       TitleCaseColumnHeaders();
                       StopProcess();
                   };
                    bwLoad.RunWorkerAsync();
                    break;
                case "tabPageSuppliers":
                    dataGridViewMain.DataSource = this.suppliersTableAdapter.GetData();
                    TitleCaseColumnHeaders();
                    groupBoxSuppliers.Enabled = false;
                    buttonSupAdd.Enabled = false;
                    buttonSupUpdate.Enabled = false;
                    StopProcess();
                    break;
                case "tabPageTreatmentSites":
                    dataGridViewMain.DataSource = this.treatment_sitesTableAdapter.GetData();
                    TitleCaseColumnHeaders();
                    groupBoxTS.Enabled = false;
                    buttonTSAdd.Enabled = false;
                    buttonTSUpdate.Enabled = false;
                    StopProcess();
                    break;
                case "tabPageReasons":
                    dataGridViewMain.DataSource = this.reasonsTableAdapter.GetData();
                    TitleCaseColumnHeaders();
                    groupBoxReasons.Enabled = false;
                    buttonResAdd.Enabled = false;
                    buttonResUpdate.Enabled = false;
                    StopProcess();
                    break;
            }
        }

        private void dataGridViewMain_SelectionChanged(object sender, EventArgs e)
        {
            groupBoxMedicines.Enabled = false;
            groupBoxAdministrations.Enabled = false;
        }

        private void medicinesBindingSource_CurrentItemChanged(object sender, EventArgs e)
        {
            if (this.purchasesTableAdapter.RowCount() > 0 && medicinesBindingSource.Current != null)
            {
                this.batchesBindingSource.Filter = "qty_left > 0 AND medicine = '" + ((DataRowView)medicinesBindingSource.Current).Row.ItemArray[1] + "'";
            }
        }

        private void batchesBindingSource_CurrentItemChanged(object sender, EventArgs e)
        {
            if (batchesBindingSource.Current != null)
            {
                String strQtyLeft = String.Format("Qty Left:{0}",
                purchasesTableAdapter.GetQtyLeftByBatch((((DataRowView)batchesBindingSource.Current).Row.ItemArray[3].ToString())));
                labelAdminQtyLeft.Text = strQtyLeft;
            }
        }
        #endregion

        #region ToolStripMainEvents
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new AboutBox().ShowDialog();
        }


        private void toolStripMenuItemExport_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbdThis = new FolderBrowserDialog();
            fbdThis.RootFolder = Environment.SpecialFolder.MyComputer;
            DialogResult drThis = fbdThis.ShowDialog();
            if (drThis == System.Windows.Forms.DialogResult.OK)
            {

                String strDest = fbdThis.SelectedPath;
                StartProcess("Backing up to " + strDest);
                BackgroundWorker bwExport = new BackgroundWorker();
                bwExport.DoWork += new DoWorkEventHandler(bwExport_DoWork);
                bwExport.RunWorkerAsync(strDest);
            }
        }

        private void toolStripMenuItemImport_Click(object sender, EventArgs e)
        {
            OpenFileDialog fdThis = new OpenFileDialog();
            fdThis.Filter = "Backup files (*.mtbak)|*.mtbak";
            fdThis.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);
            DialogResult drThis = fdThis.ShowDialog();
            if (drThis == System.Windows.Forms.DialogResult.OK)
            {
                StartProcess("Importing " + fdThis.FileName);
                BackgroundWorker bwImport = new BackgroundWorker();
                bwImport.DoWork += new DoWorkEventHandler(bwImport_DoWork);
                bwImport.RunWorkerAsync(fdThis.FileName);
            }
        }

        private void toolStripMenuItemFilter_Click(object sender, EventArgs e)
        {
            if (tabControlMain.SelectedTab.Name == "tabPageAdministrations" ||
               tabControlMain.SelectedTab.Name == "tabPagePurchases" ||
               tabControlMain.SelectedTab.Name == "tabPageDisposals")
            {
                Filter formFilter = new Filter();
                if (formFilter.ShowDialog() == DialogResult.OK)
                {
                    DateTime dtFromMidnight = new DateTime(formFilter.dateTimePickerFrom.Value.Year,
                                                           formFilter.dateTimePickerFrom.Value.Month,
                                                           formFilter.dateTimePickerFrom.Value.Day,
                                                           0, 0, 0);

                    DateTime dtToAlmostMidnight = new DateTime(formFilter.dateTimePickerTo.Value.Year,
                                                               formFilter.dateTimePickerTo.Value.Month,
                                                               formFilter.dateTimePickerTo.Value.Day,
                                                               23, 59, 59);

                    switch (tabControlMain.SelectedTab.Name)
                    {
                        case "tabPageAdministrations":
                            dataGridViewMain.DataSource = administrationsTableAdapter.GetDataByFilter(dtFromMidnight, dtToAlmostMidnight);
                            break;
                        case "tabPagePurchases":
                            dataGridViewMain.DataSource = purchasesTableAdapter.GetDataByFilter(dtFromMidnight, dtToAlmostMidnight);
                            break;
                        case "tabPageDisposals":
                            dataGridViewMain.DataSource = disposalsTableAdapter.GetDataByFilter(dtFromMidnight, dtToAlmostMidnight);
                            break;
                    }
                }
            }
            else MessageBox.Show("This dataset can not be filtered.", "Unable to filter");
        }
        #endregion

        #region Administrations
        private void buttonAdminAdd_Click(object sender, EventArgs e)
        {
            int intBatch, intSite, intReason, intQty;
            DateTime dtFinished, dtAdmin;
            String strAnimal, strAdministeredBy;
            List<String> lAnimals = new List<String>();
            strAnimal = "";
            StartProcess("Inserting...");
            if (dataGridViewGroup.RowCount > 0 && dataGridViewGroup.Visible == true)
            {
                foreach (DataGridViewRow dgvrAnimals in dataGridViewGroup.Rows)
                {
                    lAnimals.Add((String)dgvrAnimals.Cells[0].Value);
                }
            }
            else strAnimal = textBoxAdminAnimal.Text;

            intBatch = Convert.ToInt32(comboBoxAdminBatch.SelectedValue);
            dtFinished = dateTimePickerAdminFinised.Value;
            intSite = Convert.ToInt32(comboBoxAdminSite.SelectedValue);
            intReason = Convert.ToInt32(comboBoxAdminReason.SelectedValue);
            intQty = Convert.ToInt32(maskedTextBoxAdminQty.Text);
            dtAdmin = dateTimePickerAdminAdmin.Value;
            strAdministeredBy = administeredBy();
            BackgroundWorker bwInsert = new BackgroundWorker();
            bwInsert.DoWork += delegate
            {
                try
                {
                    int intMilkWP = (int)this.purchasesTableAdapter.MedMilkWP(intBatch);
                    int intMeatWP = (int)this.purchasesTableAdapter.MedMeatWP(intBatch);
                    if (strAnimal != "")
                    {
                        this.administrationsTableAdapter.InsertQuery(intBatch,
                                                                     intMilkWP,
                                                                     dtFinished,
                                                                     intMeatWP,
                                                                     intSite,
                                                                     intReason,
                                                                     strAnimal,
                                                                     intQty,
                                                                     dtAdmin,
                                                                     strAdministeredBy);
                        ClearTextBoxValue("textBoxAdminAnimal", "groupBoxAdministrations", "tabPageAdministrations");
                    }
                    else
                    {
                        foreach (String strAnimal2 in lAnimals)
                        {
                            if (strAnimal2 != null)
                            {
                                this.administrationsTableAdapter.InsertQuery(intBatch,
                                                                         intMilkWP,
                                                                         dtFinished,
                                                                         intMeatWP,
                                                                         intSite,
                                                                         intReason,
                                                                         strAnimal2,
                                                                         intQty,
                                                                         dtAdmin,
                                                                         strAdministeredBy);
                            }
                        }
                        ClearGroupDatagrid();
                    }
                    ClearMaskedTextBoxValue("maskedTextBoxAdminQty", "groupBoxAdministrations", "tabPageAdministrations");
                    SetDataBinding(this.administrationsTableAdapter.GetData());
                    StopProcess();
                    SetMessageText("Insert Complete");
                    Thread.Sleep(5000);
                }
                catch (Exception ex)
                {
                    StopProcess();
                    SetMessageText("Insert Failed " + ex.Message, true);
                    Thread.Sleep(5000);
                }
                finally
                {
                    StopProcess();
                }
            };
            bwInsert.RunWorkerAsync();
        }

        private void buttonAdminNew_Click(object sender, EventArgs e)
        {
            groupBoxAdministrations.Enabled = true;
            buttonAdminAdd.Enabled = true;
            buttonAdminUpdate.Enabled = false;
            textBoxAdminAnimal.Enabled = true;
            dataGridViewGroup.Visible = false;
        }

        private void buttonAdminEdit_Click(object sender, EventArgs e)
        {
            try
            {
                groupBoxAdministrations.Enabled = true;
                buttonAdminUpdate.Enabled = true;
                buttonAdminAdd.Enabled = false;
                dateTimePickerAdminAdmin.Value = DateTime.Parse(dataGridViewMain.CurrentRow.Cells["date_administered"].Value.ToString());
                //MORE TO DO
            }
            catch (NullReferenceException nfEx)
            {
                groupBoxAdministrations.Enabled = false;
                System.Diagnostics.Trace.WriteLine(nfEx.StackTrace, "UI Error");
                MessageBox.Show("No Row has been selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void buttonAdminUpdate_Click(object sender, EventArgs e)
        {
            StartProcess("Updating...");
            int intCurrentIndex = dataGridViewMain.CurrentRow.Index;
            this.administrationsTableAdapter.UpdateQuery(dateTimePickerAdminFinised.Value,
                                                     Convert.ToInt32(comboBoxAdminBatch.SelectedValue),
                                                     Convert.ToInt32(comboBoxAdminSite.SelectedValue),
                                                     Convert.ToInt32(comboBoxAdminReason.SelectedValue),
                                                     textBoxAdminAnimal.Text,
                                                     Convert.ToInt32(maskedTextBoxAdminQty.Text),
                                                     dateTimePickerAdminAdmin.Value,
                                                     administeredBy(),
                                                     Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["id"].Value)
                                                     );
            textBoxAdminAnimal.Text = "";
            maskedTextBoxAdminQty.Text = "";
            dataGridViewMain.DataSource = this.administrationsTableAdapter.GetData();
            MoveCursorToOriginalPosition(intCurrentIndex);
            StopProcess();
        }

        private void buttonAdminDelete_Click(object sender, EventArgs e)
        {
            StartProcess("Deleting...");
            this.administrationsTableAdapter.DeleteQuery((int)dataGridViewMain.CurrentRow.Cells["id"].Value);
            dataGridViewMain.DataSource = this.administrationsTableAdapter.GetData();
            StopProcess();
        }

        private String administeredBy()
        {
            if (radioButtonAdminFarmer.Checked) return "Farmer";
            else return "Vet";
        }

        private void buttonAdminAdd7Day_Click(object sender, EventArgs e)
        {
            String strConclusion, strNotes;

            StartProcess("Updating...");
            strConclusion = textBoxAdminReviewCon.Text;
            strNotes = textBoxAdminReviewNotes.Text;
            BackgroundWorker bwInsert = new BackgroundWorker();
            bwInsert.DoWork += delegate
            {
                try
                {
                    this.administrationsTableAdapter.UpdateSevenDayReview(strConclusion, strNotes,
                                                                          (int)dataGridViewMain.CurrentRow.Cells["id"].Value);
                    SetDataBinding(this.administrationsTableAdapter.GetData());
                    StopProcess();
                    SetMessageText("Update Complete");
                    Thread.Sleep(5000);
                }
                catch (Exception ex)
                {
                    StopProcess();
                    SetMessageText("Insert Failed " + ex.Message, true);
                    Thread.Sleep(5000);
                }
                finally
                {
                    StopProcess();
                }
            };
            bwInsert.RunWorkerAsync();
        }

        private void buttonAdmin7Day_Click(object sender, EventArgs e)
        {
            groupBoxAdmin7DayReview.Enabled = true;
            buttonAdminAdd7Day.Enabled = true;
            buttonAdminUpdate7Day.Enabled = false;
        }

        private void buttonAdminGroup_Click(object sender, EventArgs e)
        {
            groupBoxAdministrations.Enabled = true;
            dataGridViewGroup.Visible = true;
            textBoxAdminAnimal.Enabled = false;
            buttonAdminAdd.Enabled = true;
        }

        private void ClearGroupDatagrid()
        {
            if (dataGridViewGroup.InvokeRequired)
            {
                dataGridViewGroup.Invoke(new ClearGroupAdministrtions(ClearGroupDatagrid));
            }
            else
            {
                dataGridViewGroup.Rows.Clear();
            }
        }
        #endregion

        #region Purchases
        private void buttonPurAdd_Click(object sender, EventArgs e)
        {
            StartProcess("Inserting...");
            this.purchasesTableAdapter.InsertQuery(Convert.ToInt32(comboBoxPurSup.SelectedValue),
                                                   Convert.ToInt32(comboBoxPurMed.SelectedValue),
                                                   Convert.ToInt32(maskedTextBoxPurQty.Text),
                                                   textBoxPurBatch.Text,
                                                   dateTimePickerPurPur.Value,
                                                   dateTimePickerPurExp.Value);
            maskedTextBoxPurQty.Text = "";
            textBoxPurBatch.Text = "";
            dataGridViewMain.DataSource = this.purchasesTableAdapter.GetData();
            this.purchasesBindingSource.DataSource = this.purchasesTableAdapter.GetData();
            StopProcess();
        }

        private void buttonPurNew_Click(object sender, EventArgs e)
        {
            groupBoxPurchases.Enabled = true;
            buttonPurAdd.Enabled = true;
            buttonPurUpdate.Enabled = false;
        }

        private void buttonPurEdit_Click(object sender, EventArgs e)
        {
            try
            {
                groupBoxPurchases.Enabled = true;
                buttonPurUpdate.Enabled = true;
                buttonPurAdd.Enabled = false;
                //Derived columns obviously aren't going to work this way.
                comboBoxPurSup.SelectedValue = Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["supplier"].Value);
                comboBoxPurMed.SelectedValue = Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["medicine"].Value);
                //
                dateTimePickerPurPur.Value = DateTime.Parse(dataGridViewMain.CurrentRow.Cells["date_purchased"].Value.ToString());
                dateTimePickerPurExp.Value = DateTime.Parse(dataGridViewMain.CurrentRow.Cells["date_expires"].Value.ToString());
                textBoxPurBatch.Text = dataGridViewMain.CurrentRow.Cells["batch_no"].Value.ToString();
                maskedTextBoxPurQty.Text = dataGridViewMain.CurrentRow.Cells["qty_purchased"].Value.ToString();
            }
            catch (NullReferenceException nrEx)
            {
                groupBoxPurchases.Enabled = false;
                System.Diagnostics.Trace.WriteLine(nrEx.StackTrace, "UI Error");
                MessageBox.Show("No Row has been selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void buttonPurUpdate_Click(object sender, EventArgs e)
        {
            StartProcess("Updating...");
            int intCurrentIndex = dataGridViewMain.CurrentRow.Index;
            this.purchasesTableAdapter.UpdateQuery(Convert.ToInt32(comboBoxPurSup.SelectedValue),
                                                   Convert.ToInt32(comboBoxPurMed.SelectedValue),
                                                   dateTimePickerPurPur.Value,
                                                   dateTimePickerPurExp.Value,
                                                   textBoxPurBatch.Text,
                                                   Convert.ToInt32(maskedTextBoxPurQty.Text),
                                                   Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["id"].Value));
            maskedTextBoxPurQty.Text = "";
            textBoxPurBatch.Text = "";
            dataGridViewMain.DataSource = this.purchasesTableAdapter.GetData();
            this.purchasesBindingSource.DataSource = this.purchasesTableAdapter.GetData();
            MoveCursorToOriginalPosition(intCurrentIndex);
            StopProcess();
        }

        private void buttonPurDelete_Click(object sender, EventArgs e)
        {
            StartProcess("Deleting...");
            this.purchasesTableAdapter.DeleteQuery((int)dataGridViewMain.CurrentRow.Cells["id"].Value);
            dataGridViewMain.DataSource = this.purchasesTableAdapter.GetData();
            this.purchasesBindingSource.DataSource = this.purchasesTableAdapter.GetData();
            StopProcess();
        }
        #endregion

        #region Medicines
        private void buttonMedAdd_Click(object sender, EventArgs e)
        {
            StartProcess("Inserting...");
            this.medicinesTableAdapter.Insert(textBoxMedicineName.Text,
                                              Convert.ToInt32(textBoxMilkWP.Text),
                                              Convert.ToInt32(textBoxMeatWP.Text));
            textBoxMedicineName.Text = "";
            textBoxMeatWP.Text = "";
            textBoxMilkWP.Text = "";
            dataGridViewMain.DataSource = this.medicinesTableAdapter.GetData();
            this.medicinesBindingSource.DataSource = this.medicinesTableAdapter.GetData();
            StopProcess();
        }

        private void buttonMedNew_Click(object sender, EventArgs e)
        {
            groupBoxMedicines.Enabled = true;
            buttonMedAdd.Enabled = true;
            buttonMedUpdate.Enabled = false;
        }

        private void buttonMedEdit_Click(object sender, EventArgs e)
        {
            try
            {
                groupBoxMedicines.Enabled = true;
                buttonMedUpdate.Enabled = true;
                buttonMedAdd.Enabled = false;
                textBoxMedicineName.Text = Convert.ToString(dataGridViewMain.CurrentRow.Cells["name"].Value);
                textBoxMeatWP.Text = Convert.ToString(dataGridViewMain.CurrentRow.Cells["meat_withdrawal"].Value);
                textBoxMilkWP.Text = Convert.ToString(dataGridViewMain.CurrentRow.Cells["milk_withdrawal"].Value);
            }
            catch (NullReferenceException nrEx)
            {
                groupBoxSuppliers.Enabled = false;
                System.Diagnostics.Trace.WriteLine(nrEx.StackTrace, "UI Error");
                MessageBox.Show("No Row has been selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void buttonMedUpdate_Click(object sender, EventArgs e)
        {
            StartProcess("Updating...");
            int intCurrentIndex = dataGridViewMain.CurrentRow.Index;
            this.medicinesTableAdapter.Update(textBoxMedicineName.Text,
                                              Convert.ToInt32(textBoxMilkWP.Text),
                                              Convert.ToInt32(textBoxMeatWP.Text),
                                              Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["id"].Value));
            textBoxMedicineName.Text = "";
            textBoxMeatWP.Text = "";
            textBoxMilkWP.Text = "";
            dataGridViewMain.DataSource = this.medicinesTableAdapter.GetData();
            MoveCursorToOriginalPosition(intCurrentIndex);
            StopProcess();
        }

        private void groupBoxMedicines_Leave(object sender, EventArgs e)
        {
            buttonMedAdd.Enabled = false;
            buttonMedUpdate.Enabled = false;
        }

        private void buttonMedDelete_Click(object sender, EventArgs e)
        {
            StartProcess("Deleting...");
            this.medicinesTableAdapter.Delete((int)dataGridViewMain.CurrentRow.Cells["id"].Value);
            dataGridViewMain.DataSource = this.medicinesTableAdapter.GetData();
            StopProcess();
        }
        #endregion

        #region Disposals
        #endregion

        #region Suppliers
        private void buttonSupAdd_Click(object sender, EventArgs e)
        {
            StartProcess("Inserting...");
            this.suppliersTableAdapter.Insert(textBoxSupName.Text,
                                              textBoxSupPC.Text,
                                              textBoxSupAddr.Text);
            textBoxSupAddr.Text = "";
            textBoxSupName.Text = "";
            textBoxSupPC.Text = "";
            dataGridViewMain.DataSource = this.suppliersTableAdapter.GetData();
            this.suppliersBindingSource.DataSource = this.suppliersTableAdapter.GetData();
            StopProcess();
        }

        private void buttonSupNew_Click(object sender, EventArgs e)
        {
            groupBoxSuppliers.Enabled = true;
            buttonSupAdd.Enabled = true;
            buttonSupUpdate.Enabled = false;
        }

        private void buttonSupEdit_Click(object sender, EventArgs e)
        {
            try
            {
                groupBoxSuppliers.Enabled = true;
                buttonSupUpdate.Enabled = true;
                buttonSupAdd.Enabled = false;
                textBoxSupName.Text = Convert.ToString(dataGridViewMain.CurrentRow.Cells["name"].Value);
                textBoxSupPC.Text = Convert.ToString(dataGridViewMain.CurrentRow.Cells["postcode"].Value);
                textBoxSupAddr.Text = Convert.ToString(dataGridViewMain.CurrentRow.Cells["address"].Value);
            }
            catch (NullReferenceException nrEx)
            {
                groupBoxSuppliers.Enabled = false;
                System.Diagnostics.Trace.WriteLine(nrEx.StackTrace, "UI Error");
                MessageBox.Show("No Row has been selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void buttonSupUpdate_Click(object sender, EventArgs e)
        {
            StartProcess("Updating...");
            int intCurrentIndex = dataGridViewMain.CurrentRow.Index;
            this.suppliersTableAdapter.Update(textBoxSupName.Text,
                                              textBoxSupPC.Text,
                                              textBoxSupAddr.Text,
                                              Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["id"].Value));
            textBoxSupAddr.Text = "";
            textBoxSupName.Text = "";
            textBoxSupPC.Text = "";
            dataGridViewMain.DataSource = this.suppliersTableAdapter.GetData();
            this.suppliersBindingSource.DataSource = this.suppliersTableAdapter.GetData();
            MoveCursorToOriginalPosition(intCurrentIndex);
            StopProcess();
        }

        private void buttonSupDelete_Click(object sender, EventArgs e)
        {
            StartProcess("Deleting...");
            this.suppliersTableAdapter.Delete((int)dataGridViewMain.CurrentRow.Cells["id"].Value);
            dataGridViewMain.DataSource = this.suppliersTableAdapter.GetData();
            this.suppliersBindingSource.DataSource = this.suppliersTableAdapter.GetData();
            StopProcess();
        }
        #endregion

        #region Treatment Sites
        private void buttonTSAdd_Click(object sender, EventArgs e)
        {
            StartProcess("Inserting...");
            this.treatment_sitesTableAdapter.Insert(textBoxTSTS.Text);
            textBoxTSTS.Text = "";
            dataGridViewMain.DataSource = this.treatment_sitesTableAdapter.GetData();
            this.treatmentsitesBindingSource.DataSource = this.treatment_sitesTableAdapter.GetData();
            StopProcess();
        }

        private void buttonTSNew_Click(object sender, EventArgs e)
        {
            groupBoxTS.Enabled = true;
            buttonTSAdd.Enabled = true;
            buttonTSUpdate.Enabled = false;
        }

        private void buttonTSEdit_Click(object sender, EventArgs e)
        {
            try
            {
                groupBoxTS.Enabled = true;
                buttonTSUpdate.Enabled = true;
                buttonTSAdd.Enabled = false;
                textBoxTSTS.Text = dataGridViewMain.CurrentRow.Cells["description"].Value.ToString();
            }
            catch (NullReferenceException nrEx)
            {
                groupBoxTS.Enabled = false;
                System.Diagnostics.Trace.WriteLine(nrEx.StackTrace, "UI Error");
                MessageBox.Show("No Row has been selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void buttonTSUpdate_Click(object sender, EventArgs e)
        {
            StartProcess("Updating...");
            int intCurrentIndex = dataGridViewMain.CurrentRow.Index;
            this.treatment_sitesTableAdapter.Update(textBoxTSTS.Text,
                                            Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["id"].Value));
            textBoxTSTS.Text = "";
            dataGridViewMain.DataSource = this.treatment_sitesTableAdapter.GetData();
            this.treatmentsitesBindingSource.DataSource = this.treatment_sitesTableAdapter.GetData();
            MoveCursorToOriginalPosition(intCurrentIndex);
            StopProcess();
        }

        private void buttonTSDelete_Click(object sender, EventArgs e)
        {
            StartProcess("Deleting...");
            this.treatment_sitesTableAdapter.Delete((int)dataGridViewMain.CurrentRow.Cells["id"].Value);
            dataGridViewMain.DataSource = this.treatment_sitesTableAdapter.GetData();
            this.treatmentsitesBindingSource.DataSource = this.treatment_sitesTableAdapter.GetData();
            StopProcess();
        }
        #endregion

        #region Reasons
        private void buttonResAdd_Click(object sender, EventArgs e)
        {
            StartProcess("Inserting...");
            this.reasonsTableAdapter.Insert(textBoxResRes.Text);
            textBoxResRes.Text = "";
            dataGridViewMain.DataSource = this.reasonsTableAdapter.GetData();
            this.reasonsBindingSource.DataSource = this.reasonsTableAdapter.GetData();
            StopProcess();
        }

        private void buttonResNew_Click(object sender, EventArgs e)
        {
            groupBoxReasons.Enabled = true;
            buttonResAdd.Enabled = true;
            buttonResUpdate.Enabled = false;
        }

        private void buttonResEdit_Click(object sender, EventArgs e)
        {
            try
            {
                groupBoxReasons.Enabled = true;
                buttonResUpdate.Enabled = true;
                buttonResAdd.Enabled = false;
                textBoxResRes.Text = dataGridViewMain.CurrentRow.Cells["description"].Value.ToString();
            }
            catch (NullReferenceException nrEx)
            {
                groupBoxReasons.Enabled = false;
                System.Diagnostics.Trace.WriteLine(nrEx.StackTrace, "UI Error");
                MessageBox.Show("No Row has been selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void buttonResUpdate_Click(object sender, EventArgs e)
        {
            StartProcess("Updating...");
            int intCurrentIndex = dataGridViewMain.CurrentRow.Index;
            this.reasonsTableAdapter.Update(textBoxResRes.Text,
                                            Convert.ToInt32(dataGridViewMain.CurrentRow.Cells["id"].Value));
            textBoxResRes.Text = "";
            dataGridViewMain.DataSource = this.reasonsTableAdapter.GetData();
            this.reasonsBindingSource.DataSource = this.reasonsTableAdapter.GetData();
            MoveCursorToOriginalPosition(intCurrentIndex);
            StopProcess();
        }

        private void buttonResDelete_Click(object sender, EventArgs e)
        {
            StartProcess("Deleting...");
            this.reasonsTableAdapter.Delete((int)dataGridViewMain.CurrentRow.Cells["id"].Value);
            dataGridViewMain.DataSource = this.reasonsTableAdapter.GetData();
            this.reasonsBindingSource.DataSource = this.reasonsTableAdapter.GetData();
            StopProcess();
        }
        #endregion

        #region Methods
        private void StartProcess(String strMessage)
        {
            toolStripStatusLabelCurrentOpperation.Text = strMessage;
            toolStripProgressBar.Visible = true;
        }

        private void StopProcess()
        {
            if (statusStripMain.InvokeRequired)
            {
                this.Invoke(new SetStatusCallback(StopProcess));
            }
            else
            {
                toolStripProgressBar.Visible = false;
                toolStripStatusLabelCurrentOpperation.Text = "Idle";
                toolStripStatusLabelCurrentOpperation.ForeColor = System.Drawing.SystemColors.ControlText;
            }
        }

        private void SetTabPageToAdministrations()
        {
            if (tabControlMain.InvokeRequired)
            {
                this.Invoke(new SetTabPageCallback(SetTabPageToAdministrations));
            }
            else
            {
                tabControlMain.SelectedTab = tabControlMain.TabPages[1];
                tabControlMain.SelectedTab = tabControlMain.TabPages[0];
                groupBoxAdministrations.Enabled = false;
                groupBoxAdmin7DayReview.Enabled = false;
            }
        }

        private void SetDataBinding(object NewBindingSource)
        {
            if (dataGridViewMain.InvokeRequired)
            {
                this.Invoke(new SetDataBindingCallback(SetDataBinding), new object[] { NewBindingSource });
            }
            else
            {
                dataGridViewMain.DataSource = (DataTable)NewBindingSource;
            }
        }

        private void TitleCaseColumnHeaders()
        {
            if (dataGridViewMain.InvokeRequired)
            {
                this.Invoke(new TitleCaseColumnHeadersCallback(TitleCaseColumnHeaders));
            }
            else
            {
                dataGridViewMain.Columns["id"].Visible = false;
                foreach (DataGridViewColumn dgvcThis in dataGridViewMain.Columns)
                {
                    dgvcThis.HeaderText = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(dgvcThis.HeaderText.Replace("_", " "));
                    if (dgvcThis.Name == "milk_ok" ||
                       dgvcThis.Name == "meat_ok" ||
                       dgvcThis.Name.Contains("date"))
                    {
                        dgvcThis.DefaultCellStyle.Format = "d";
                    }
                }
                dataGridViewMain.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
            }
        }

        private void MoveCursorToOriginalPosition(int intLastKnownIndex)
        {
            dataGridViewMain.CurrentCell = dataGridViewMain[1, intLastKnownIndex];
            dataGridViewMain.Rows[intLastKnownIndex].Selected = true;
        }

        public static string GetDataDirectory()
        {
            if (ApplicationDeployment.IsNetworkDeployed)
            {
                return ApplicationDeployment.CurrentDeployment.DataDirectory;
            }
            else
            {
                return Application.StartupPath;
            }
        }

        private void SetMessageText(String strMessage, Boolean bolWarning = false)
        {
            if (statusStripMain.InvokeRequired)
            {
                this.Invoke(new SetMessageTextCallback(SetMessageText), new object[] { strMessage, bolWarning });
            }
            else
            {
                toolStripStatusLabelCurrentOpperation.Text = strMessage;
                if (bolWarning) toolStripStatusLabelCurrentOpperation.ForeColor = System.Drawing.Color.OrangeRed;
                else toolStripStatusLabelCurrentOpperation.ForeColor = System.Drawing.SystemColors.ControlText;
            }
        }

        private void BindDataSources()
        {
            try
            {
                this.purchasesTableAdapter.Fill(this.app_DataDataSet.purchases);
                this.treatment_sitesTableAdapter.Fill(this.app_DataDataSet.treatment_sites);
                this.reasonsTableAdapter.Fill(this.app_DataDataSet.reasons);
                this.disposalsTableAdapter.Fill(this.app_DataDataSet.disposals);
                this.suppliersTableAdapter.Fill(this.app_DataDataSet.suppliers);
                this.purchasesTableAdapter.Fill(this.app_DataDataSet.purchases);
                this.medicinesTableAdapter.Fill(this.app_DataDataSet.medicines);
                this.administrationsTableAdapter.Fill(this.app_DataDataSet.administrations);
                this.app_DataDataSet.GetChanges();
            }
            catch (System.Data.SqlServerCe.SqlCeException sqlceEx)
            {
                MessageBox.Show(String.Format("The database in use is corrupt or unusable by Medicine Tracker 3.{0}{0}" +
                                              "Please Import a valid Medicine Tracker 3 database. (Please note, databases " +
                                              "from Medicine Tracker 2 are incompatible with Medicine Tracker 3)",
                                              Environment.NewLine),
                                              "Loading Database Failed",
                                              MessageBoxButtons.OK,
                                              MessageBoxIcon.Error);
                System.Diagnostics.Trace.WriteLine(sqlceEx.StackTrace);
                StopProcess();
            }
        }

        private void ClearTextBoxValue(String strComponentName, String strContainer, String strTabPage)
        {
            if (tabControlMain.Controls[strTabPage].Controls[strContainer].Controls[strComponentName].InvokeRequired)
            {
                this.Invoke(new ClearTextBoxValueCallback(ClearTextBoxValue), new object[] { strComponentName, strContainer, strTabPage });
            }
            else
            {
                ((TextBox)tabControlMain.Controls[strTabPage].Controls[strContainer].Controls[strComponentName]).Text = "";
            }
        }

        private void ClearMaskedTextBoxValue(String strComponentName, String strContainer, String strTabPage)
        {

            if (tabControlMain.Controls[strTabPage].Controls[strContainer].Controls[strComponentName].InvokeRequired)
            {
                this.Invoke(new ClearTextBoxValueCallback(ClearMaskedTextBoxValue), new object[] { strComponentName, strContainer, strTabPage });
            }
            else
            {
                ((MaskedTextBox)tabControlMain.Controls[strTabPage].Controls[strContainer].Controls[strComponentName]).Text = "";
            }
        }
        #endregion

        #region Delegates
        private delegate void SetStatusCallback();

        private delegate void SetTabPageCallback();

        private delegate void SetDataBindingCallback(object objBindingSource);

        private delegate void TitleCaseColumnHeadersCallback();

        private delegate void SetMessageTextCallback(String strMessage, Boolean bolWaring = false);

        private delegate void BindDataSourcesCallback();

        private delegate void GetComponentValueThreadSafeCallback(String strControlName, int intControlType);

        private delegate void ClearTextBoxValueCallback(String strControlName, String strContainer, String strTabPage);

        private delegate void ClearGroupAdministrtions();
        #endregion

        #region Background Workers
        void bgwLoad_DoWork(object sender, DoWorkEventArgs e)
        {
            this.BeginInvoke(new BindDataSourcesCallback(BindDataSources));
            SetTabPageToAdministrations();
            BindDataSources();
            SetDataBinding(this.app_DataDataSet.administrations);
            TitleCaseColumnHeaders();
            this.Invalidate();
            StopProcess();
        }

        void bwExport_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                String strDest = (String)e.Argument + "\\" + DateTime.Now.ToLongDateString() + ".mtbak";
                String strSource = GetDataDirectory() + "\\App_Data.sdf";
                System.IO.File.Copy(strSource,
                                    strDest,
                                    true);
                StopProcess();
                SetMessageText("Backup Complete");
                Thread.Sleep(5000);
            }
            catch (UnauthorizedAccessException uaEx)
            {
                MessageBox.Show(String.Format("You do not have permission to save to this folder.  If you would like to save the file here please " +
                                "close the application and run it with administrator privilages{0}{0}(Right Click on program icon and " +
                                "click 'Run as administrator'", Environment.NewLine),
                                "Backup Failed",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
                System.Diagnostics.Trace.WriteLine(uaEx.Message);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Backup Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                StopProcess();
            }
        }

        void bwImport_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                String strDest1 = GetDataDirectory() + "\\App_Data.sdf";
                String strDest2 = GetDataDirectory() + "\\App_Data.sdfbac";
                System.IO.File.Copy((String)e.Argument, strDest2, true);
                System.IO.File.Replace(strDest2, strDest1, strDest1 + "replacebak");
                System.IO.File.Delete(strDest1 + "replacebak");
                this.BeginInvoke(new BindDataSourcesCallback(BindDataSources));
                SetTabPageToAdministrations();
                SetDataBinding(this.administrationsTableAdapter.GetData());
                BindDataSources();
                TitleCaseColumnHeaders();
                StopProcess();
                SetMessageText("Import Complete.");
                Thread.Sleep(5000);
                StopProcess();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Import Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion
    }
}